import {
  DataSourceConfig,
  DataSourceAdapter,
  StandardAlert,
  DataSourceType,
  DataSourceStatus,
  DataSourceStats,
  DataSourceTestResult,
} from '@/types/datasource.types';
import { PrometheusAdapter } from '@/adapters/prometheus.adapter';
import logger from '@utils/logger';

/**
 * 数据源管理服务
 * 负责管理多个告警数据源，提供统一的接口
 */
class DataSourceService {
  private adapters: Map<DataSourceType, DataSourceAdapter>;
  private dataSources: Map<string, DataSourceConfig>;
  private healthCheckIntervals: Map<string, NodeJS.Timeout>;

  constructor() {
    this.adapters = new Map();
    this.dataSources = new Map();
    this.healthCheckIntervals = new Map();

    // 注册默认适配器
    this.registerAdapter(new PrometheusAdapter());
  }

  /**
   * 注册数据源适配器
   */
  registerAdapter(adapter: DataSourceAdapter): void {
    this.adapters.set(adapter.type, adapter);
    logger.info(`Registered adapter for ${adapter.type}`);
  }

  /**
   * 添加数据源
   */
  async addDataSource(config: DataSourceConfig): Promise<{
    success: boolean;
    message: string;
    data?: DataSourceConfig;
  }> {
    try {
      // 验证配置
      const validation = this.validateConfig(config);
      if (!validation.valid) {
        return {
          success: false,
          message: validation.errors.join(', '),
        };
      }

      // 测试连接
      const testResult = await this.testDataSource(config);
      if (!testResult.success) {
        return {
          success: false,
          message: `Connection test failed: ${testResult.message}`,
        };
      }

      // 初始化元数据
      if (!config.metadata) {
        config.metadata = {
          createdBy: 'system',
          totalAlertsReceived: 0,
          errorCount: 0,
        };
      }

      // 保存数据源
      this.dataSources.set(config.id, config);

      // 启动健康检查
      if (config.healthCheck?.enabled) {
        this.startHealthCheck(config);
      }

      logger.info(`Data source added: ${config.name} (${config.type})`);

      return {
        success: true,
        message: 'Data source added successfully',
        data: config,
      };
    } catch (error: any) {
      logger.error(`Failed to add data source: ${error.message}`);
      return {
        success: false,
        message: error.message,
      };
    }
  }

  /**
   * 更新数据源
   */
  async updateDataSource(
    id: string,
    updates: Partial<DataSourceConfig>
  ): Promise<{
    success: boolean;
    message: string;
    data?: DataSourceConfig;
  }> {
    const existing = this.dataSources.get(id);
    if (!existing) {
      return {
        success: false,
        message: 'Data source not found',
      };
    }

    // 合并配置
    const updated: DataSourceConfig = {
      ...existing,
      ...updates,
      id, // 保持 ID 不变
      metadata: {
        createdBy: existing.metadata?.createdBy || 'system',
        ...(existing.metadata || {}),
        ...(updates.metadata || {}),
      },
    };

    // 如果连接配置变了，重新测试
    if (updates.connection) {
      const testResult = await this.testDataSource(updated);
      if (!testResult.success) {
        return {
          success: false,
          message: `Connection test failed: ${testResult.message}`,
        };
      }
    }

    // 更新数据源
    this.dataSources.set(id, updated);

    // 重启健康检查
    this.stopHealthCheck(id);
    if (updated.healthCheck?.enabled) {
      this.startHealthCheck(updated);
    }

    logger.info(`Data source updated: ${updated.name}`);

    return {
      success: true,
      message: 'Data source updated successfully',
      data: updated,
    };
  }

  /**
   * 删除数据源
   */
  deleteDataSource(id: string): { success: boolean; message: string } {
    const existing = this.dataSources.get(id);
    if (!existing) {
      return {
        success: false,
        message: 'Data source not found',
      };
    }

    // 停止健康检查
    this.stopHealthCheck(id);

    // 删除数据源
    this.dataSources.delete(id);

    logger.info(`Data source deleted: ${existing.name}`);

    return {
      success: true,
      message: 'Data source deleted successfully',
    };
  }

  /**
   * 获取数据源
   */
  getDataSource(id: string): DataSourceConfig | undefined {
    return this.dataSources.get(id);
  }

  /**
   * 获取所有数据源
   */
  getAllDataSources(): DataSourceConfig[] {
    return Array.from(this.dataSources.values());
  }

  /**
   * 获取启用的数据源
   */
  getEnabledDataSources(): DataSourceConfig[] {
    return Array.from(this.dataSources.values())
      .filter((ds) => ds.enabled)
      .sort((a, b) => a.priority - b.priority);
  }

  /**
   * 从所有数据源获取告警
   */
  async fetchAlertsFromAllSources(options?: {
    startTime?: Date;
    endTime?: Date;
    filters?: Record<string, any>;
  }): Promise<StandardAlert[]> {
    const enabledSources = this.getEnabledDataSources();
    const alertPromises = enabledSources.map((source) => this.fetchAlertsFromSource(source.id, options));

    const results = await Promise.allSettled(alertPromises);

    const allAlerts: StandardAlert[] = [];
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        allAlerts.push(...result.value);
      } else {
        const source = enabledSources[index];
        logger.error(`Failed to fetch alerts from ${source.name}: ${result.reason}`);

        // 更新错误计数
        if (source.metadata) {
          source.metadata.errorCount = (source.metadata.errorCount || 0) + 1;
        }
      }
    });

    // 去重（基于 fingerprint）
    const uniqueAlerts = this.deduplicateAlerts(allAlerts);

    return uniqueAlerts;
  }

  /**
   * 从指定数据源获取告警
   */
  async fetchAlertsFromSource(
    sourceId: string,
    options?: {
      startTime?: Date;
      endTime?: Date;
      filters?: Record<string, any>;
    }
  ): Promise<StandardAlert[]> {
    const source = this.dataSources.get(sourceId);
    if (!source) {
      throw new Error(`Data source not found: ${sourceId}`);
    }

    if (!source.enabled) {
      logger.warn(`Data source is disabled: ${source.name}`);
      return [];
    }

    const adapter = this.adapters.get(source.type);
    if (!adapter) {
      throw new Error(`No adapter found for type: ${source.type}`);
    }

    try {
      const alerts = await adapter.fetchAlerts(source, options);

      // 更新元数据
      if (source.metadata) {
        source.metadata.lastSyncAt = new Date();
        source.metadata.totalAlertsReceived = (source.metadata.totalAlertsReceived || 0) + alerts.length;
      }

      return alerts;
    } catch (error: any) {
      logger.error(`Failed to fetch alerts from ${source.name}: ${error.message}`);

      // 更新错误计数和状态
      if (source.metadata) {
        source.metadata.errorCount = (source.metadata.errorCount || 0) + 1;
      }
      source.status = DataSourceStatus.ERROR;

      throw error;
    }
  }

  /**
   * 测试数据源连接
   */
  async testDataSource(config: DataSourceConfig): Promise<DataSourceTestResult> {
    const adapter = this.adapters.get(config.type);
    if (!adapter) {
      return {
        success: false,
        message: `No adapter available for ${config.type}`,
      };
    }

    try {
      const connectionTest = await adapter.testConnection(config);

      if (!connectionTest.success) {
        return {
          success: false,
          message: connectionTest.message,
          details: {
            connectionTest: false,
            authTest: false,
            dataFetchTest: false,
            latency: connectionTest.latency || 0,
            errors: [connectionTest.message],
          },
        };
      }

      // 尝试获取样本数据
      let sampleAlerts: StandardAlert[] = [];
      let dataFetchTest = false;

      try {
        sampleAlerts = await adapter.fetchAlerts(config);
        dataFetchTest = true;
      } catch (error: any) {
        logger.warn(`Sample data fetch failed: ${error.message}`);
      }

      return {
        success: true,
        message: 'Connection test successful',
        details: {
          connectionTest: true,
          authTest: true,
          dataFetchTest,
          sampleAlerts: sampleAlerts.slice(0, 3), // 返回前3个样本
          latency: connectionTest.latency || 0,
        },
      };
    } catch (error: any) {
      return {
        success: false,
        message: error.message,
        details: {
          connectionTest: false,
          authTest: false,
          dataFetchTest: false,
          latency: 0,
          errors: [error.message],
        },
      };
    }
  }

  /**
   * 获取数据源统计信息
   */
  getDataSourceStats(id: string): DataSourceStats | null {
    const source = this.dataSources.get(id);
    if (!source || !source.metadata) {
      return null;
    }

    const totalRequests = (source.metadata.totalAlertsReceived || 0) + (source.metadata.errorCount || 0);
    const successRate = totalRequests > 0 ? ((source.metadata.totalAlertsReceived || 0) / totalRequests) * 100 : 0;
    const errorRate = totalRequests > 0 ? ((source.metadata.errorCount || 0) / totalRequests) * 100 : 0;

    return {
      id: source.id,
      name: source.name,
      type: source.type,
      status: source.status,
      alertsReceived: source.metadata.totalAlertsReceived || 0,
      lastSyncAt: source.metadata.lastSyncAt,
      averageLatency: 0, // TODO: Implement latency tracking
      errorRate,
      successRate,
    };
  }

  /**
   * 验证数据源配置
   */
  private validateConfig(config: DataSourceConfig): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    if (!config.id) errors.push('ID is required');
    if (!config.name) errors.push('Name is required');
    if (!config.type) errors.push('Type is required');
    if (!config.connection?.url) errors.push('Connection URL is required');
    if (!this.adapters.has(config.type)) errors.push(`Unsupported data source type: ${config.type}`);

    return {
      valid: errors.length === 0,
      errors,
    };
  }

  /**
   * 启动健康检查
   */
  private startHealthCheck(config: DataSourceConfig): void {
    if (!config.healthCheck?.enabled || !config.healthCheck.interval) {
      return;
    }

    const interval = setInterval(async () => {
      const adapter = this.adapters.get(config.type);
      if (!adapter) return;

      try {
        const isHealthy = await adapter.healthCheck(config);
        config.status = isHealthy ? DataSourceStatus.ACTIVE : DataSourceStatus.ERROR;

        if (config.metadata) {
          config.metadata.lastHealthCheck = new Date();
        }

        logger.debug(`Health check for ${config.name}: ${isHealthy ? 'OK' : 'FAILED'}`);
      } catch (error: any) {
        logger.error(`Health check error for ${config.name}: ${error.message}`);
        config.status = DataSourceStatus.ERROR;
      }
    }, config.healthCheck.interval * 1000);

    this.healthCheckIntervals.set(config.id, interval);
  }

  /**
   * 停止健康检查
   */
  private stopHealthCheck(id: string): void {
    const interval = this.healthCheckIntervals.get(id);
    if (interval) {
      clearInterval(interval);
      this.healthCheckIntervals.delete(id);
    }
  }

  /**
   * 去重告警
   */
  private deduplicateAlerts(alerts: StandardAlert[]): StandardAlert[] {
    const seen = new Map<string, StandardAlert>();

    for (const alert of alerts) {
      const existing = seen.get(alert.fingerprint);

      // 如果已存在，保留优先级更高的数据源的告警
      if (existing) {
        const existingSource = this.dataSources.get(existing.sourceId);
        const currentSource = this.dataSources.get(alert.sourceId);

        if (currentSource && existingSource && currentSource.priority < existingSource.priority) {
          seen.set(alert.fingerprint, alert);
        }
      } else {
        seen.set(alert.fingerprint, alert);
      }
    }

    return Array.from(seen.values());
  }

  /**
   * 清理资源
   */
  shutdown(): void {
    // 停止所有健康检查
    this.healthCheckIntervals.forEach((interval) => clearInterval(interval));
    this.healthCheckIntervals.clear();

    logger.info('DataSourceService shutdown complete');
  }
}

export default new DataSourceService();
